﻿using Infrastructure.Model.DI;
using Microsoft.Extensions.Logging;
using Model.EntityModel.Auth;
using Repository.IRepository.ISysRepository;
using SqlSugar;
using Group = Model.EntityModel.Auth.Group;

namespace Repository.Repository.SysRepository
{

    /// <summary>
    /// 部门与组别仓储实现
    /// </summary>
    [AppService(ServiceType = typeof(IDeptGroupRepository), ServiceLifetime = LifeTime.Transient)]
    public class DeptGroupRepository : SqlSugarBaseRepository<DeptGroup>, IDeptGroupRepository
    {
        private readonly ILogger<DeptGroupRepository> _logger;

        public DeptGroupRepository(ILogger<DeptGroupRepository> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 获取部门关联的组集合（异步）
        /// </summary>
        public async Task<List<DeptGroup>> GetDeptGroupsAsync(string deptId)
        {
            try
            {
                return await _db.Queryable<DeptGroup>()
                    .Where(dg => dg.DeptId == deptId)
                    .ToListAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取部门[{deptId}]关联组失败");
                throw;
            }
        }
        /// <summary>
        /// 获取部门可用的组别（异步）
        /// </summary>
        /// <param name="deptId">部门ID</param>
        /// <returns>可用的组别ID列表</returns>
        public async Task<List<string>> GetAvailableGroupsAsync(string deptId)
        {
            if (string.IsNullOrEmpty(deptId))
            {
                _logger.LogWarning("部门ID为空，无法获取可用组别");
                return new List<string>();
            }

            try
            {
                // 第一步：获取当前部门已关联的组别ID列表
                var excludedGroupIds = await _db.Queryable<DeptGroup>()
                    .Where(subDg => subDg.DeptId == deptId)
                    .Select(subDg => subDg.GroupId)
                    .ToListAsync();

                // 第二步：查询所有激活的组别，并排除已关联的组别
                var availableGroups = await _db.Queryable<DeptGroup>()
                    .Where(dg => dg.IsActive == "Y" && !excludedGroupIds.Contains(dg.GroupId))
                    .Select(dg => dg.GroupId)
                    .ToListAsync();

                return availableGroups;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取部门[{deptId}]可用组别失败");
                throw;
            }
        }
        /// <summary>
        /// 获取部门关联的组集合（同步）
        /// </summary>
        public List<DeptGroup> GetDeptGroups(string deptId)
        {
            try
            {
                return _db.Queryable<DeptGroup>()
                    .Where(dg => dg.DeptId == deptId)
                    .ToList();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取部门[{deptId}]关联组失败");
                throw;
            }
        }

        /// <summary>
        /// 批量添加组到部门（异步）
        /// </summary>
        public async Task<bool> AddGroupsToDeptAsync(string deptId, List<string> groupIds)
        {
            if (string.IsNullOrEmpty(deptId) || !groupIds?.Any() == true) return false;

            try
            {
                // 去重并过滤空值
                var distinctGroupIds = groupIds.Distinct().Where(g => !string.IsNullOrEmpty(g)).ToList();
                if (!distinctGroupIds.Any()) return false;

                // 获取已存在的关联
                var existingGroups = await _db.Queryable<DeptGroup>()
                    .Where(dg => dg.DeptId == deptId)
                    .Select(dg => dg.GroupId)
                    .ToListAsync();

                // 筛选出新的关联
                var newGroupIds = distinctGroupIds.Except(existingGroups).ToList();
                if (!newGroupIds.Any()) return true;

                // 批量插入关系记录
                var relations = newGroupIds.Select(g => new DeptGroup
                {
                    Id = Guid.NewGuid().ToString(),
                    DeptId = deptId,
                    GroupId = g,
                    IsActive = "Y",
                    CreatedAt = DateTime.Now
                }).ToList();

                int affectedRows = await _db.Insertable(relations).ExecuteCommandAsync();
                return affectedRows > 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"添加组到部门[{deptId}]失败");
                throw;
            }
        }

        /// <summary>
        /// 批量添加组到部门（同步）
        /// </summary>
        public bool AddGroupsToDept(string deptId, List<string> groupIds)
        {
            if (string.IsNullOrEmpty(deptId) || !groupIds?.Any() == true) return false;

            try
            {
                // 去重并过滤空值
                var distinctGroupIds = groupIds.Distinct().Where(g => !string.IsNullOrEmpty(g)).ToList();
                if (!distinctGroupIds.Any()) return false;

                // 获取已存在的关联
                var existingGroups = _db.Queryable<DeptGroup>()
                    .Where(dg => dg.DeptId == deptId)
                    .Select(dg => dg.GroupId)
                    .ToList();

                // 筛选出新的关联
                var newGroupIds = distinctGroupIds.Except(existingGroups).ToList();
                if (!newGroupIds.Any()) return true;

                // 批量插入关系记录
                var relations = newGroupIds.Select(g => new DeptGroup
                {
                    Id = Guid.NewGuid().ToString(),
                    DeptId = deptId,
                    GroupId = g,
                    IsActive = "Y",
                    CreatedAt = DateTime.Now
                }).ToList();

                int affectedRows = _db.Insertable(relations).ExecuteCommand();
                return affectedRows > 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"添加组到部门[{deptId}]失败");
                throw;
            }
        }

        /// <summary>
        /// 批量移除部门下的组（异步）
        /// </summary>
        public async Task<bool> RemoveGroupsFromDeptAsync(string deptId, List<string> groupIds)
        {
            if (string.IsNullOrEmpty(deptId) || !groupIds?.Any() == true) return false;

            try
            {
                int affectedRows = await _db.Deleteable<DeptGroup>()
                    .Where(r => r.DeptId == deptId && groupIds.Contains(r.GroupId))
                    .ExecuteCommandAsync();

                return affectedRows > 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"从部门[{deptId}]移除组失败");
                throw;
            }
        }

        /// <summary>
        /// 批量移除部门下的组（同步）
        /// </summary>
        public bool RemoveGroupsFromDept(string deptId, List<string> groupIds)
        {
            if (string.IsNullOrEmpty(deptId) || !groupIds?.Any() == true) return false;

            try
            {
                int affectedRows = _db.Deleteable<DeptGroup>()
                    .Where(r => r.DeptId == deptId && groupIds.Contains(r.GroupId))
                    .ExecuteCommand();

                return affectedRows > 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"从部门[{deptId}]移除组失败");
                throw;
            }
        }

        /// <summary>
        /// 更新部门组关系的激活状态（异步）
        /// </summary>
        public async Task<bool> UpdateDeptGroupStatusAsync(string relationId, string isActive)
        {
            if (string.IsNullOrEmpty(relationId) || string.IsNullOrWhiteSpace(isActive)) return false;

            try
            {
                // 参数校验
                if (!"Y".Equals(isActive, StringComparison.OrdinalIgnoreCase)
                    && !"N".Equals(isActive, StringComparison.OrdinalIgnoreCase))
                    throw new ArgumentException("无效的状态参数");

                // 更新状态
                int affectedRows = await _db.Updateable<DeptGroup>()
                    .SetColumns(it => it.IsActive == isActive)
                    .SetColumns(it => it.ModifiedAt == DateTime.Now) // 添加修改时间
                    .Where(r => r.Id == relationId)
                    .ExecuteCommandAsync();

                return affectedRows > 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新关系[{relationId}]状态失败");
                throw;
            }
        }

        /// <summary>
        /// 更新部门组关系的激活状态（同步）
        /// </summary>
        public bool UpdateDeptGroupStatus(string relationId, string isActive)
        {
            if (string.IsNullOrEmpty(relationId) || string.IsNullOrWhiteSpace(isActive)) return false;

            try
            {
                // 参数校验
                if (!"Y".Equals(isActive, StringComparison.OrdinalIgnoreCase)
                    && !"N".Equals(isActive, StringComparison.OrdinalIgnoreCase))
                    throw new ArgumentException("无效的状态参数");

                // 更新状态
                int affectedRows = _db.Updateable<DeptGroup>()
                    .SetColumns(it => it.IsActive == isActive)
                    .SetColumns(it => it.ModifiedAt == DateTime.Now) // 添加修改时间
                    .Where(r => r.Id == relationId)
                    .ExecuteCommand();

                return affectedRows > 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新关系[{relationId}]状态失败");
                throw;
            }
        }

        /// <summary>
        /// 检查部门是否已关联指定组（异步）
        /// </summary>
        public async Task<bool> DeptGroupExistsAsync(string deptId, string groupId)
        {
            if (string.IsNullOrEmpty(deptId) || string.IsNullOrEmpty(groupId)) return false;

            try
            {
                return await _db.Queryable<DeptGroup>()
                    .Where(r => r.DeptId == deptId
                                && r.GroupId == groupId
                                && r.IsActive == "Y")
                    .AnyAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"检查部门[{deptId}]是否包含组[{groupId}]失败");
                throw;
            }
        }

        /// <summary>
        /// 检查部门是否已关联指定组（同步）
        /// </summary>
        public bool DeptGroupExists(string deptId, string groupId)
        {
            if (string.IsNullOrEmpty(deptId) || string.IsNullOrEmpty(groupId)) return false;

            try
            {
                return _db.Queryable<DeptGroup>()
                    .Where(r => r.DeptId == deptId
                                && r.GroupId == groupId
                                && r.IsActive == "Y")
                    .Any();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"检查部门[{deptId}]是否包含组[{groupId}]失败");
                throw;
            }
        }
        /// <summary>
        /// 根据部门ID获取可用组别列表
        /// </summary>
        /// <param name="deptId">部门唯一标识</param>
        /// <returns>可用的组别集合</returns>
        public List<Group> GetAvailableGroupsForDept(string deptId)
        {
            if (string.IsNullOrEmpty(deptId))
            {
                _logger?.LogWarning("输入的部门ID为空");
                return new List<Group>();
            }

            try
            {
                // 构建联合查询：查找有效部门关联 + 有效组别基础信息
                var groups = _db.Queryable<DeptGroup>()
                    .InnerJoin<Group>((dg, gm) => dg.GroupId == gm.Id)  // 使用组别ID关联
                    .Where((dg, gm) =>
                        dg.DeptId == deptId &&
                        dg.IsActive == "Y" &&
                        gm.IsActive == "Y")
                    .Select((dg, gm) => new Group
                    {
                        Id = gm.Id,
                        Name = gm.Name,
                        Category = gm.Category,
                  
                    })
                    .ToList();

                _logger?.LogInformation($"部门[{deptId}]查询到{groups.Count}个可用组别");
                return groups;
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, $"查询部门[{deptId}]的组别时发生错误");
                return new List<Group>();
            }
        }

    }

}
